package ihm.panel.camera.streaming;


import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.LinkedList;

import javax.swing.JPanel;

import network.ssl.KrakenSSLClient;

import tools.math.Math_;

public class StreamPanel extends JPanel implements Runnable {

	private static final long serialVersionUID = 1L;

	private StreamPlayerPanel parent_panel;

	// server
	private KrakenSSLClient cmd_client;
	private KrakenSSLClient vid_client;
	private int REFRESH_RATE = 50;
	
	// stats
	private LinkedList<Double> fps_buf = new LinkedList<Double>();
	private double fps = 0;
	private double fps_tmp = 0;
	private long frame_count = 0;
	//private double sample_size = 50;
	private double frame_compute_time = 0;

	// image
	private BufferedImage img;

	/**
	 * Constructeur.
	 */
	public StreamPanel(StreamPlayerPanel parent) {
		this.parent_panel = parent;
	}

	/**
	 * Recoit une BufferedImage compressee.
	 * @return BufferedImage
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public BufferedImage readJPG() throws UnknownHostException, IOException {
		if(vid_client != null) {
			if(vid_client.getFrame() != null) {
				return vid_client.getFrame().getImage();
			} 
			//else System.out.println("Frame null!");
		}
		//else System.out.println("Socket null!");
		
		return null;
	}


	// Drawing

	/**
	 * Dessine l'ecran.
	 */
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if(img != null)
			g.drawImage(img, 0, 0, getWidth(), getHeight(), 0, 0, 320, 240, null);
	}

	@Override
	public void run() {
		while(true) {
			try {
				BufferedImage tmp = null;
				frame_compute_time = System.currentTimeMillis();
				do {
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} while((tmp = readJPG()) == img);
				frame_compute_time = System.currentTimeMillis() - frame_compute_time;
				
				img = tmp;
			} catch (IOException e) {
				e.printStackTrace();
			}

			// display
			repaint();
					
			// fps
			fps_tmp = 1000/frame_compute_time;
			
			if(fps > 1) {
				if(fps_tmp < fps+2) {
					fps_buf.addFirst(fps_tmp);
				}
			}
			else
				fps_buf.addFirst(fps_tmp);
			
			//fps_buf.addFirst(fps_tmp);
			if(fps_buf.size() >= REFRESH_RATE) fps_buf.removeLast(); // fifo
			fps = Math_.mean(fps_buf);
	
			// mises à jour des labels toutes les 10 frames
			if(frame_count%REFRESH_RATE == 0) {
				parent_panel.changeFPS(new String((int) fps+""));
				cmd_client.setFps((int) fps);
				fps_buf.removeAll(fps_buf);
			}
	
			frame_count++;
			//System.out.println("loop "+frame_count);
		}
	}
	
	public void play() {
		vid_client.setStream_state(1);
		cmd_client.setStream_state(1);
	}
	
	public void pause() {
		vid_client.setStream_state(2);
		cmd_client.setStream_state(2);
	}
	
	public void stop() {
		vid_client.setStream_state(0);
		cmd_client.setStream_state(0);
		img = null;
		repaint();
	}
	
	// Getters

	public double getFps() { return fps; }

	public void setCmd_client(KrakenSSLClient cmd_client) { this.cmd_client = cmd_client; }
	public void setVid_client(KrakenSSLClient vid_client) { this.vid_client = vid_client; }
	
}
